home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Text⁄Files / Voyeur 1.1.1 / Voyeur ƒ / MSG Shell ƒ / msg graphics.c < prev    next >
Text File  |  1994-02-26  |  13KB  |  497 lines

  1. /**********************************************************************\
  2.  
  3. File:        msg graphics.c
  4.  
  5. Purpose:    This module handles opening/closing/updating all windows:
  6.             help window and about windows.  This includes
  7.             manipulating offscreen bitmaps for fun and no profit.
  8.  
  9.  
  10. Voyeur -- a no-frills file viewer
  11. Copyright ©1993-4, Mark Pilgrim
  12.  
  13. This program is free software; you can redistribute it and/or modify
  14. it under the terms of the GNU General Public License as published by
  15. the Free Software Foundation; either version 2 of the License, or
  16. (at your option) any later version.
  17.  
  18. This program is distributed in the hope that it will be useful,
  19. but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21. GNU General Public License for more details.
  22.  
  23. You should have received a copy of the GNU General Public License
  24. along with this program in a file named "GNU General Public License".
  25. If not, write to the Free Software Foundation, 675 Mass Ave,
  26. Cambridge, MA 02139, USA.
  27.  
  28. \**********************************************************************/
  29.  
  30. #include "msg graphics.h"
  31. #include "msg about.h"
  32. #include "msg help.h"
  33. #include "msg dialogs.h"
  34. #include "msg error.h"
  35. #include "msg menus.h"
  36. #include "msg environment.h"
  37. #include "msg prefs.h"
  38. #include "program globals.h"
  39. #include "v.h"
  40. #include "v graphics.h"
  41. #include "v window maintenance.h"
  42.  
  43. Boolean            gInitedWindowBounds[NUM_WINDOWS];
  44. Rect            gMainScreenBounds;
  45. Rect            gWindowBounds[NUM_WINDOWS];
  46. GDHandle        gBiggestDevice;
  47. WindowPtr        gTheWindow[NUM_WINDOWS];
  48. int                gWindowWidth[NUM_WINDOWS];
  49. int                gWindowHeight[NUM_WINDOWS];
  50. Str255            gWindowTitle[NUM_WINDOWS];
  51. int                gWindowType[NUM_WINDOWS];
  52. Boolean            gOffscreenNeedsUpdate[NUM_WINDOWS];
  53. int                gNumHelp;
  54.  
  55. /* internal stuff */
  56. Rect            bRect[NUM_WINDOWS];
  57. Ptr                myBits[NUM_WINDOWS];
  58. CGrafPort        myCGrafPort[NUM_WINDOWS];
  59. CGrafPtr        myCGrafPtr[NUM_WINDOWS];
  60. CTabHandle        ourCMHandle[NUM_WINDOWS];
  61. GrafPort        myGrafPort[NUM_WINDOWS];
  62. GrafPtr            myGrafPtr[NUM_WINDOWS];
  63. int                gLastDepth[NUM_WINDOWS];
  64. int                gMaxDepth[NUM_WINDOWS];
  65.  
  66. void InitMSGGraphics(void)
  67. {
  68.     int                i;
  69.     
  70.     gWindowWidth[kAbout]=210;
  71.     gWindowHeight[kAbout]=210;
  72.     
  73.     gWindowWidth[kAboutMSG]=243;
  74.     gWindowHeight[kAboutMSG]=243;
  75.     
  76.     gWindowWidth[kHelp]=300;
  77.     gWindowHeight[kHelp]=250;
  78.     
  79.     for (i=0; i<MAX_WINDOWS; i++)
  80.     {
  81.         gWindowWidth[kMainWindow+i]=440;
  82.         gWindowHeight[kMainWindow+i]=225;
  83.         gWindowType[kMainWindow+i]=noGrowDocProc;
  84.         gWindowTitle[kMainWindow+i][0]=0x00;
  85.         gMaxDepth[kMainWindow+i]=1;
  86.     }
  87.     
  88.     for (i=0; i<NUM_WINDOWS; i++)
  89.     {
  90.         myCGrafPtr[i]=myGrafPtr[i]=gTheWindow[i]=0L;
  91.         gInitedWindowBounds[i]=FALSE;
  92.         gOffscreenNeedsUpdate[i]=TRUE;
  93.     }
  94.     
  95.     gMaxDepth[kAbout]=8;
  96.     gMaxDepth[kAboutMSG]=1;
  97.     gMaxDepth[kHelp]=1;
  98.     
  99.     gWindowType[kAbout]=1778;
  100.     gWindowType[kAboutMSG]=plainDBox;
  101.     gWindowType[kHelp]=noGrowDocProc;
  102.     
  103.     StuffHex(gWindowTitle[kHelp], "\p0448656c70");
  104.     gWindowTitle[kAbout][0]=gWindowTitle[kAboutMSG][0]==0x00;
  105. }
  106.  
  107. void OpenTheWindow(int index)
  108. {
  109.     unsigned long        dummy;
  110.     
  111.     if (!gTheWindow[index])
  112.     {
  113.         if (!gInitedWindowBounds[index])
  114.         {
  115.             if (index==kMainWindow)
  116.             {
  117.                 gWindowBounds[index].left=10;
  118.                 gWindowBounds[index].top=50;
  119.             }
  120.             else if (index>kMainWindow)
  121.             {
  122.                 gWindowBounds[index].left=gWindowBounds[index-1].left+20;
  123.                 gWindowBounds[index].top=gWindowBounds[index-1].top+20;
  124.                 if (gWindowBounds[index].left+gWindowWidth[index]>gMainScreenBounds.right)
  125.                     gWindowBounds[index].left=10;
  126.                 if (gWindowBounds[index].top+gWindowHeight[index]>gMainScreenBounds.bottom)
  127.                     gWindowBounds[index].top=50;
  128.             }
  129.             else if (index==kHelp)
  130.             {
  131.                 gWindowBounds[index].left=10;
  132.                 gWindowBounds[index].top=50;
  133.             }
  134.             else
  135.             {
  136.                 gWindowBounds[index].left = gMainScreenBounds.left + (((gMainScreenBounds.right -
  137.                             gMainScreenBounds.left) - gWindowWidth[index]) / 2);
  138.                 gWindowBounds[index].top = 9+ gMainScreenBounds.top + (((gMainScreenBounds.bottom -
  139.                             gMainScreenBounds.top) - gWindowHeight[index]) / 2);
  140.                 if (gWindowBounds[index].top < 30)
  141.                     gWindowBounds[index].top = 30;
  142.             }
  143.             gWindowBounds[index].bottom = gWindowBounds[index].top + gWindowHeight[index];
  144.             gWindowBounds[index].right = gWindowBounds[index].left + gWindowWidth[index];
  145.             gInitedWindowBounds[index]=TRUE;
  146.         }
  147.         
  148.         if(gHasColorQD)
  149.         {
  150.             gTheWindow[index] = NewCWindow(0L, &gWindowBounds[index], gWindowTitle[index],
  151.                 TRUE, gWindowType[index], (WindowPtr)-1L, (index!=kAbout), 0L);
  152.         }
  153.         else
  154.         {
  155.             gTheWindow[index] = NewWindow(0L, &gWindowBounds[index], gWindowTitle[index],
  156.                 TRUE, gWindowType[index], (WindowPtr)-1L, (index!=kAbout), 0L);
  157.         }
  158.  
  159.         bRect[index] = gTheWindow[index]->portRect;
  160.     }
  161.     
  162.     if (gTheWindow[index])
  163.     {
  164.         SelectWindow(gTheWindow[index]);
  165.         SetPort(gTheWindow[index]);
  166.         UpdateTheWindow(index);
  167.         if (index==kAboutMSG)
  168.             Delay(30, &dummy);
  169.     }
  170.     else ErrorString("\pThere is not enough memory to open the window.","\p");
  171. }
  172.  
  173. void GetMainScreenBounds(void)
  174. {
  175.     gMainScreenBounds = screenBits.bounds;
  176.     gMainScreenBounds.top += MBarHeight;
  177. }
  178.  
  179. int GetWindowDepth(int index)
  180. {
  181.     Rect        tempRect;
  182.     long        biggestSize;
  183.     long        tempSize;
  184.     GDHandle    thisHandle;
  185.     
  186.     if (gHasColorQD)
  187.     {
  188.         if (gTheWindow[index])
  189.         {
  190.             thisHandle = GetDeviceList();
  191.             gBiggestDevice = 0L;
  192.             biggestSize = 0L;
  193.             
  194.             while (thisHandle)
  195.             {
  196.                 if (TestDeviceAttribute(thisHandle, screenDevice) &&
  197.                             TestDeviceAttribute(thisHandle, screenActive))
  198.                     if (SectRect(&(gTheWindow[index]->portRect), &((**thisHandle).gdRect),
  199.                                 &tempRect))
  200.                         if (biggestSize < (tempSize =
  201.                                 ((long)(tempRect.bottom - tempRect.top))
  202.                                 * ((long)(tempRect.right - tempRect.left))))
  203.                         {
  204.                             biggestSize = tempSize;
  205.                             gBiggestDevice = thisHandle;
  206.                         }
  207.                 thisHandle = GetNextDevice(thisHandle);
  208.             }
  209.             
  210.             if (gBiggestDevice)
  211.                 return (**(**gBiggestDevice).gdPMap).pixelSize;
  212.             else
  213.                 return 1;
  214.         }
  215.         else
  216.         {
  217.             return (**(**GetMainDevice()).gdPMap).pixelSize;
  218.         }
  219.     }
  220.     else
  221.     {
  222.         return 1;
  223.     }
  224. }
  225.  
  226. void UpdateTheWindow(int index)
  227. {
  228.     long        offRowBytes, sizeOfOff;
  229.     int            theDepth, i, err;
  230.     GDHandle    oldDevice;
  231.  
  232.     if (((theDepth = GetWindowDepth(index)) > 2) && (gMaxDepth[index]>2))
  233.     {
  234.         /* if we just changed from one color depth to another color depth */
  235.         if((myCGrafPtr[index] != 0L) && (gLastDepth[index] != theDepth))
  236.         {
  237.             DisposeHandle((**(myCGrafPort[index]).portPixMap).pmTable);
  238.             DisposePtr((**(myCGrafPort[index]).portPixMap).baseAddr);
  239.             CloseCPort(myCGrafPtr[index]);
  240.             myCGrafPtr[index] = 0L;            
  241.             gOffscreenNeedsUpdate[index]=TRUE;
  242.         }
  243.         
  244.         if (myCGrafPtr[index]==0L)
  245.         {
  246.             /* if we just switched from b/w to color, delete the b/w port */
  247.             if(myGrafPtr[index] != 0L)
  248.             {
  249.                 DisposePtr(myGrafPort[index].portBits.baseAddr);
  250.                 ClosePort(myGrafPtr[index]);
  251.                 myGrafPtr[index] = 0L;
  252.                 gOffscreenNeedsUpdate[index]=TRUE;
  253.             }
  254.             
  255.             if (gBiggestDevice)
  256.             {
  257.                 oldDevice = GetGDevice();
  258.                 SetGDevice(gBiggestDevice);
  259.             }
  260.             else
  261.                 oldDevice = 0L;
  262.             
  263.             myCGrafPtr[index] = &myCGrafPort[index];
  264.             OpenCPort(myCGrafPtr[index]);
  265.             gLastDepth[index] = theDepth = (**(myCGrafPort[index]).portPixMap).pixelSize;
  266.             if (theDepth>gMaxDepth[index])
  267.                 gLastDepth[index]=theDepth=gMaxDepth[index];
  268.             
  269.             offRowBytes = (((theDepth * (bRect[index].right - bRect[index].left)) + 15) >> 4) << 1;
  270.             sizeOfOff = (long)(bRect[index].bottom - bRect[index].top) * offRowBytes;
  271.             OffsetRect(&bRect[index], -bRect[index].left, -bRect[index].top);
  272.             
  273.             myBits[index] = NewPtr(sizeOfOff);
  274.             if(myBits[index] == 0L)
  275.             {
  276.                 CloseCPort(myCGrafPtr[index]);
  277.                 myCGrafPtr[index]=0L;
  278.                 ErrorString("\pThere is not enough memory to open the window.","\p");
  279.             }
  280.             
  281.             (**(myCGrafPort[index]).portPixMap).baseAddr = myBits[index];
  282.             (**(myCGrafPort[index]).portPixMap).rowBytes = offRowBytes + 0x8000;
  283.             (**(myCGrafPort[index]).portPixMap).bounds = bRect[index];
  284.             
  285.             myCGrafPort[index].portRect = bRect[index];
  286.             
  287.             ourCMHandle[index] = (**(**gBiggestDevice).gdPMap).pmTable;
  288.             err = HandToHand(&ourCMHandle[index]);
  289.             if(err != noErr)
  290.             {
  291.                 DisposePtr((**(myCGrafPort[index]).portPixMap).baseAddr);
  292.                 CloseCPort(myCGrafPtr[index]);
  293.                 myCGrafPtr[index]=0L;
  294.                 ErrorString("\pThere is not enough memory to open the window.","\p");
  295.             }
  296.             
  297.             for(i = 0; i <= (**ourCMHandle[index]).ctSize; i++)
  298.                 (**ourCMHandle[index]).ctTable[i].value = i;
  299.             (**ourCMHandle[index]).ctFlags &= 0x7fff;
  300.             (**ourCMHandle[index]).ctSeed = GetCTSeed();
  301.             
  302.             (**(myCGrafPort[index]).portPixMap).pmTable = ourCMHandle[index];
  303.             
  304.             if (oldDevice)
  305.                 SetGDevice(oldDevice);
  306.         }
  307.         
  308.         UpdateTheWindowColor(index);
  309.     }
  310.     else
  311.     {
  312.         if (myGrafPtr[index]==0L)
  313.         {
  314.             if(myCGrafPtr[index] != 0L)
  315.             {
  316.                 DisposeHandle((**(myCGrafPort[index]).portPixMap).pmTable);
  317.                 DisposePtr((**(myCGrafPort[index]).portPixMap).baseAddr);
  318.                 CloseCPort(myCGrafPtr[index]);
  319.                 myCGrafPtr[index] = 0L;
  320.                 gOffscreenNeedsUpdate[index]=TRUE;
  321.             }
  322.             
  323.             myGrafPtr[index] = &myGrafPort[index];
  324.             OpenPort(myGrafPtr[index]);
  325.             
  326.             offRowBytes = (((bRect[index].right - bRect[index].left) + 15) >> 4) << 1;
  327.             sizeOfOff = (long)(bRect[index].bottom - bRect[index].top) * offRowBytes;
  328.             OffsetRect(&bRect[index], -bRect[index].left, -bRect[index].top);
  329.             
  330.             myBits[index] = NewPtr(sizeOfOff);
  331.             if(myBits[index] == 0L)
  332.             {
  333.                 ClosePort(myGrafPtr[index]);
  334.                 myGrafPtr[index]=0L;
  335.                 ErrorString("\pThere is not enough memory to open the window.", "\p");
  336.             }
  337.             
  338.             myGrafPort[index].portBits.baseAddr = myBits[index];
  339.             myGrafPort[index].portBits.rowBytes = offRowBytes;
  340.             myGrafPort[index].portBits.bounds = bRect[index];
  341.             myGrafPort[index].portRect = bRect[index];            
  342.         }
  343.         
  344.         UpdateTheWindowBW(index);
  345.     }
  346.     
  347.     ValidRect(&(gTheWindow[index]->portRect));
  348. }
  349.  
  350. void UpdateTheWindowColor(int index)
  351. {
  352.     GDHandle    oldDevice;
  353.     RgnHandle    oldClipRgn;
  354.     RgnHandle    newClipRgn;
  355.     
  356.     if (gOffscreenNeedsUpdate[index])
  357.     {
  358.         oldDevice = GetGDevice();
  359.         SetGDevice(gBiggestDevice);
  360.         oldClipRgn = myCGrafPort[index].clipRgn;
  361.         newClipRgn=NewRgn();
  362.         SetRectRgn(newClipRgn, 0, 0, gWindowWidth[index], gWindowHeight[index]);
  363.         
  364.         myCGrafPort[index].clipRgn=newClipRgn;
  365.             
  366.         SetPort((GrafPtr)myCGrafPtr[index]);
  367.         
  368.         switch (index)
  369.         {
  370.             case kAbout:
  371.                 DrawTheAboutBox(TRUE);
  372.                 break;
  373.             case kAboutMSG:
  374.                 DrawTheCarpet();
  375.                 break;
  376.             case kHelp:
  377.                 DrawTheHelp(TRUE);
  378.                 break;
  379.             default:
  380.                 if (IsProgramWindow(gTheWindow[index]))
  381.                     DrawTheWindowColor(index-kMainWindow);
  382.                 break;
  383.         }
  384.         SetGDevice(oldDevice);
  385.         myCGrafPort[index].clipRgn = oldClipRgn;
  386.         DisposeRgn(newClipRgn);
  387.         gOffscreenNeedsUpdate[index]=FALSE;
  388.     }
  389.     
  390.     SetPort(gTheWindow[index]);
  391.     
  392.     CopyBits(&(((GrafPtr)myCGrafPtr[index])->portBits),
  393.                 &(gTheWindow[index]->portBits), &bRect[index], &bRect[index], 0, 0L);
  394. }
  395.  
  396. void UpdateTheWindowBW(int index)
  397. {
  398.     RgnHandle    oldClipRgn;
  399.     RgnHandle    newClipRgn;
  400.     
  401.     if (gOffscreenNeedsUpdate[index])
  402.     {
  403.         oldClipRgn = myGrafPort[index].clipRgn;
  404.         newClipRgn=NewRgn();
  405.         SetRectRgn(newClipRgn, 0, 0, gWindowWidth[index], gWindowHeight[index]);
  406.         myCGrafPort[index].clipRgn=newClipRgn;
  407.         SetPort(myGrafPtr[index]);
  408.         switch (index)
  409.         {
  410.             case kAbout:
  411.                 DrawTheAboutBox(FALSE);
  412.                 break;
  413.             case kAboutMSG:
  414.                 DrawTheCarpet();
  415.                 break;
  416.             case kHelp:
  417.                 DrawTheHelp(FALSE);
  418.                 break;
  419.             default:
  420.                 if (IsProgramWindow(gTheWindow[index]))
  421.                     DrawTheWindowBW(index-kMainWindow);
  422.                 break;
  423.         }
  424.         myGrafPort[index].clipRgn = oldClipRgn;
  425.         DisposeRgn(newClipRgn);
  426.         gOffscreenNeedsUpdate[index]=FALSE;
  427.     }
  428.     
  429.     SetPort(gTheWindow[index]);
  430.     
  431.     CopyBits(&(myGrafPtr[index]->portBits),
  432.                 &(gTheWindow[index]->portBits), &bRect[index], &bRect[index], 0, 0L);
  433. }
  434.  
  435. void UpdateHelpWindow(void)
  436. {
  437.     gOffscreenNeedsUpdate[kHelp]=TRUE;
  438.     OpenTheWindow(kHelp);
  439. }
  440.  
  441. void CloseTheWindow(int index)
  442. {
  443.     DisposeWindow(gTheWindow[index]);
  444.     gTheWindow[index]=0L;
  445.     gInitedWindowBounds[index]=FALSE;
  446.     
  447.     if (index==kHelp)
  448.         gOffscreenNeedsUpdate[kHelp]=TRUE;
  449. }
  450.  
  451. void DrawThePicture(PicHandle *thePict, int whichPict, int x, int y)
  452. {
  453.     Rect            temp;
  454.     
  455.     if (*thePict==0L)
  456.         *thePict=(PicHandle)GetPicture(whichPict);
  457.     
  458.     HLock(*thePict);
  459.     temp.top=y;
  460.     temp.left=x;
  461.     temp.bottom=temp.top+(***thePict).picFrame.bottom-(***thePict).picFrame.top;
  462.     temp.right=temp.left+(***thePict).picFrame.right-(***thePict).picFrame.left;
  463.     DrawPicture(*thePict, &temp);
  464.     HUnlock(*thePict);
  465. }
  466.  
  467. void ReleaseThePict(PicHandle *thePict)
  468. {
  469.     if (*thePict!=0L)
  470.     {
  471.         ReleaseResource(*thePict);
  472.         *thePict=0L;
  473.     }
  474. }
  475.  
  476. void ShutDownMSGGraphics(void)
  477. {
  478.     int                i;
  479.     
  480.     for (i=0; i<NUM_WINDOWS; i++)
  481.     {
  482.         if ((myCGrafPtr[i]!=0L) || (myGrafPtr[i]!=0L))
  483.             DisposPtr(myBits[i]);
  484.         if(myCGrafPtr[i] != 0L)
  485.         {
  486.             DisposeHandle((**(myCGrafPort[i]).portPixMap).pmTable);
  487.             CloseCPort(myCGrafPtr[i]);
  488.             myCGrafPtr[i] = 0L;
  489.         }
  490.         if(myGrafPtr[i] != 0L)
  491.         {
  492.             ClosePort(myGrafPtr[i]);
  493.             myGrafPtr[i] = 0L;
  494.         }
  495.     }
  496. }
  497.